
#define _DCF77_C_

#include <avr/io.h>
#include <avr/interrupt.h>
#include <string.h>
#include <util/delay.h>
#include <stdio.h>

#include "config.h"
#include "typedefs.h"
#include "timebase.h"
#include "dcf77.h"
#include "usart0.h"

unsigned char ucBitNo;
unsigned char ucParityErr;
unsigned char ucParity[3]; // 3 ParityBits
unsigned char ucDCF77FrameValid;

unsigned char DCF77Init(void){
	// TODO: init timer for dcf timing
}

unsigned char DCF77Decode(t_time *localTime, t_date *localDate){
  unsigned char ucMinute;
  unsigned char ucHour;
  unsigned char ucDay;
  unsigned char ucMonth;
  unsigned char ucYear;

  unsigned char s[64];

  ucMinute = ucDCF77Bits[21] + ucDCF77Bits[22]*2 +
             ucDCF77Bits[23]*4 + ucDCF77Bits[24]*8 +
			 ucDCF77Bits[25]*10 + ucDCF77Bits[26]*20 + ucDCF77Bits[27]*40;
			 
  ucHour = ucDCF77Bits[29] + ucDCF77Bits[30]*2 +
             ucDCF77Bits[31]*4 + ucDCF77Bits[32]*8 +
			 ucDCF77Bits[33]*10 + ucDCF77Bits[34]*20;
			 
  ucDay = ucDCF77Bits[36] + ucDCF77Bits[37]*2 +
             ucDCF77Bits[38]*4 + ucDCF77Bits[39]*8 +
			 ucDCF77Bits[40]*10 + ucDCF77Bits[41]*20;

  ucMonth = ucDCF77Bits[45] + ucDCF77Bits[46]*2 +
             ucDCF77Bits[47]*4 + ucDCF77Bits[48]*8 +
			 ucDCF77Bits[49]*10;
			 
  ucYear = ucDCF77Bits[50] + ucDCF77Bits[51]*2 +
             ucDCF77Bits[52]*4 + ucDCF77Bits[53]*8 +
			 ucDCF77Bits[54]*10 + ucDCF77Bits[55]*20 + 
			 ucDCF77Bits[56]*40 + ucDCF77Bits[57]*80;

  localTime->minute = ucMinute;
  localTime->hour = ucHour;

  localDate->ucDay = ucDay;
  localDate->ucMonth = ucMonth;
  localDate->ucYear = ucYear;

#ifdef _DEBUG_
      sprintf((char*)s,"20%02d-%02d-%02d, %02d:%02d", ucYear, ucMonth, ucDay, ucHour, ucMinute);
      Uart_puts_0("Actual Time: ");
      Uart_puts_0((char*)s);
      Uart_puts_0("\r\n");
#endif
  return 0;
}


ISR (INT1_vect) {			//Beginn eines Zeitsignals
  static unsigned int uiLastTick = 0;
  unsigned int uiDiff = systemTime.uiTick - uiLastTick;
  if(uiDiff > 384) ucBitNo = 0; // timeDiff > 1.5sec -> new minute starts
  if ((EICRA & 0x0C) == 0x0C){ // Rising Edge
    if (ucDCF77FrameValid){
	  ucDCF77FrameRecv = 1;
	  ucDCF77FrameValid = 0;
	}
  
    EICRA &= ~(1<<ISC10);
  } else if ((EICRA & 0x0C) == 0x08){ // falling edge

      //Parity speichern
      //beginn von Bereich P1/P2/P3
      if (ucBitNo ==  21 || ucBitNo ==  29 || ucBitNo ==  36) 
         {
         ucParityErr = 0;
         };
      //Speichern von P1
      if (ucBitNo ==  28) {ucParity[0] = ucParityErr;};
      //Speichern von P2
      if (ucBitNo ==  35) {ucParity[1] = ucParityErr;};
      //Speichern von P3
      if (ucBitNo ==  58) {ucParity[2] = ucParityErr;};

	// count ticks on Falling edge

	if (uiDiff > 20 && uiDiff < 40) ucDCF77Bits[ucBitNo] = 0;
	else if (uiDiff > 40 && uiDiff < 60){
	  ucDCF77Bits[ucBitNo] = 1;
	  ucParityErr = ucParityErr ^ 1;
    }


    ucBitNo++;
    if (ucBitNo == 59 &&
	    ucParity[0] == ucDCF77Bits[28] &&
	    ucParity[1] == ucDCF77Bits[35] &&
	    ucParity[2] == ucDCF77Bits[58]) {
      ucBitNo = 0;
	  ucDCF77FrameValid = 1;
    }

    EICRA |= (1<<ISC10); // Set to rising Edge
  } else{
    EICRA |= (1<<ISC10) | (1<<ISC11); // Reset to rising edge
  }
  uiLastTick = systemTime.uiTick;
}












#undef _DCF77_C_
